home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMICUS04.ADF / C / gfxmem.c < prev    next >
C/C++ Source or Header  |  1985-11-03  |  8KB  |  279 lines

  1. /*
  2. Path: puff!uwvax!harvard!seismo!caip!louie
  3. From: louie@trantor.UMD.EDU
  4. Subject: gfxmem.c - graphical memory usage for your amiga
  5. Date: 28 Oct 85 05:26:32 GMT
  6. Organization: Rutgers Univ., New Brunswick, N.J.
  7.  
  8. From: Louis A. Mamakos <louie@trantor.UMD.EDU>
  9.  
  10. Here's a program that I hacked together today to figure out how some of the 
  11. graphics primitives work.  It creates a window, and plots a bar graph in it 
  12. showing how much memory is free and how much is in use.  If you have so 
  13. called FAST memory external, then it's size is displayed too.  
  14.  
  15. As you resize the window, the bar graphs are rescaled.  This program shows 
  16. you how to create a window, and how to use the RectFill() function.  You'll 
  17. also see how to handle some of the Intuition messages about your window.  I 
  18. wasn't able to make the timer.device thingy work, so there's a bit of a 
  19. kludge in there to use AmigaDOS Delay() subroutine.  
  20.  
  21. Oh well, it just a day's hack anyway. The hack to find how much memory is in 
  22. the system is from Amiga's AVAIL program.  I don't claim to know how it 
  23. works;  it's methods certainly aren't documented.  Enjoy. 
  24. */
  25.  
  26.  
  27. /*
  28.  *  gfxmem.c - display memory used graphically.  This program is a freebie; 
  29.  *  give it to anyone you want, just don't sell it.  If you do, the software
  30.  *  police will be out to get YOU! 
  31.  *
  32.  *  Copyright (C) 1985,  Louis A. Mamakos
  33.  */
  34.  
  35. #include <exec/types.h>
  36. #include <exec/nodes.h>
  37. #include <exec/lists.h>
  38. #include <exec/exec.h>
  39. #include <exec/execbase.h>
  40. #include <exec/ports.h>
  41. #include <exec/devices.h>
  42. #include <exec/memory.h>
  43. #include <devices/timer.h>
  44. #include <hardware/blit.h>
  45. #include <graphics/copper.h>
  46. #include <graphics/regions.h>
  47. #include <graphics/rastport.h>
  48. #include <graphics/gfxbase.h>
  49. #include <graphics/gfxmacros.h>
  50. #include <graphics/gels.h>
  51. #include <intuition/intuition.h>
  52.  
  53. extern struct ExecBase *SysBase;
  54. struct IntuitionBase *IntuitionBase;
  55. struct GfxBase *GfxBase;
  56. struct MsgPort *timerport, *CreatePort();
  57. struct timerequest timereq;
  58. struct NewWindow NewWindow = {
  59.    10, 10, 400, 50,           /* sizes */
  60.    0, 1,                      /* pens */
  61.    CLOSEWINDOW | SIZEVERIFY | NEWSIZE | REFRESHWINDOW,/* IDCMP flags */
  62.    WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | WINDOWSIZING | SIMPLE_REFRESH,
  63.    NULL, NULL,                /*gadget, checkmark */
  64.    "GfxMem",                  /* title */
  65.    NULL, NULL,                /* screen, bitmap */
  66.    100, 30, 640, 60,          /* min and max sizing */
  67.    WBENCHSCREEN               /* on the workbench screen */
  68. };
  69.  
  70. ULONG   AvailMem ();
  71. ULONG   ChipMax, FastMax, ChipFree, FastFree;
  72. ULONG   ChipLargest, FastLargest;
  73. int   dont_draw;
  74.  
  75. /*
  76.  *  maxsize -- determine the total maximum size for all regions
  77.  *   of the given type.  This code must be executed while
  78.  *   FORBIDDEN (it accesses shared system structures).
  79.  */
  80. ULONG
  81. maxsize (t)
  82.     unsigned long t;
  83. {
  84.     /* THIS CODE MUST ALWAYS BE CALLED WHILE FORBIDDEN */
  85.     ULONG size = 0;
  86.     struct MemHeader *mem;
  87.     struct ExecBase *eb = SysBase;
  88.  
  89.     for (mem = (struct MemHeader *) eb -> MemList.lh_Head;
  90.                         mem -> mh_Node.ln_Succ; mem = mem -> mh_Node.ln_Succ)
  91.        if (mem -> mh_Attributes & t)
  92.           size += ((ULONG) mem -> mh_Upper - (ULONG) mem -> mh_Lower);
  93.     return size;
  94. }
  95.  
  96. getsizes()
  97. {
  98.    if (ChipMax == 0) {  /* only do this once */
  99.       Forbid ();
  100.       ChipMax = maxsize (MEMF_CHIP);
  101.       FastMax = maxsize (MEMF_FAST);
  102.       Permit();
  103.    }
  104.    ChipFree = AvailMem (MEMF_CHIP);
  105.    ChipLargest = AvailMem (MEMF_CHIP | MEMF_LARGEST);
  106.    FastFree = AvailMem (MEMF_FAST);
  107.    FastLargest = AvailMem (MEMF_FAST | MEMF_LARGEST);
  108. }
  109.  
  110. starttimer()
  111. {
  112.    timereq.tr_time.tv_secs = 1;
  113.    timereq.tr_time.tv_micro = 0;
  114.    timereq.tr_node.io_Command = TR_ADDREQUEST;
  115.    timereq.tr_node.io_Flags = 0;
  116.    timereq.tr_node.io_Error = 0;
  117.    DoIO((char *) &timereq.tr_node);
  118. }
  119.  
  120. /*
  121.  *  Main function.  Call intution to create a new window for us on the
  122.  *  screen.  Go from there.
  123.  */
  124. main(argc, argv)
  125.    int argc;
  126.    char **argv;
  127. {
  128.    struct Window *w;
  129.    struct IntuiMessage *msg, *GetMsg();
  130.    struct MsgPort *timerport, *CreatePort();
  131.    static struct timerequest timereq;
  132.  
  133.    timerport = NULL;
  134.    IntuitionBase = (struct IntuitionBase *)
  135.                    OpenLibrary("intuition.library", 0);
  136.    if (IntuitionBase == NULL)
  137.       exit(1);
  138.    GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0);
  139.    if (GfxBase == NULL) {
  140.       CloseLibrary(IntuitionBase);
  141.       exit(2);
  142.    }
  143.  
  144.    if ((w = (struct Window *) OpenWindow(&NewWindow)) == NULL) {
  145.       CloseLibrary(GfxBase);
  146.       CloseLibrary(IntuitionBase);
  147.       exit(3);
  148.    }
  149.    if ((timerport = CreatePort("Timer Port", 0)) == NULL) {
  150.       CloseWindow(w);
  151.       CloseLibrary(GfxBase);
  152.       CloseLibrary(IntuitionBase);
  153.       exit(5);
  154.    }
  155.    timereq.tr_node.io_Message.mn_ReplyPort = timerport;
  156.    timereq.tr_node.io_Message.mn_Length = sizeof (timereq);
  157.    timereq.tr_node.io_Message.mn_Node.ln_Type = NT_MESSAGE;
  158.    timereq.tr_node.io_Message.mn_Node.ln_Pri = 0;
  159.    timereq.tr_node.io_Message.mn_Node.ln_Succ = NULL;
  160.    timereq.tr_node.io_Message.mn_Node.ln_Pred = NULL;
  161.    timereq.tr_node.io_Error = 0;
  162.    timereq.tr_node.io_Flags = 0;
  163.  
  164.    if (OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &timereq, 0) != 0) {
  165.       DeletePort(timerport);
  166.       CloseWindow(w);
  167.       CloseLibrary(GfxBase);
  168.       CloseLibrary(IntuitionBase);
  169.       exit(4);
  170.    }
  171.  
  172.    redraw(w, TRUE);
  173.    /* starttimer();  */
  174.    for(;;) {
  175. #ifdef   notdef
  176.    Wait((1 << w->UserPort->mp_SigBit) |
  177.            (1 << timerport->mp_SigBit));
  178. #endif
  179. /*
  180.  *  Next two lines are a kludge;  if I can figure out how to make the timer
  181.  *  device work, than that's the right way to do it.  Oh well...
  182.  */
  183.       Delay(25);
  184.       redraw(w, FALSE);
  185.       while (msg = GetMsg(w->UserPort)) {
  186.          switch (msg->Class) {
  187.          case CLOSEWINDOW:
  188.             ReplyMsg(msg);
  189.             CloseDevice(&timereq);
  190.             DeletePort(timerport);
  191.             CloseWindow(w);
  192.             CloseLibrary(GfxBase);
  193.             CloseLibrary(IntuitionBase);
  194.             exit(0);
  195.  
  196.          case REFRESHWINDOW:
  197.             BeginRefresh(w);
  198.             dont_draw = 0;
  199.             redraw(w, TRUE);
  200.             EndRefresh(w, TRUE);
  201.  
  202.          case NEWSIZE:
  203.             dont_draw = 0;
  204.             redraw(w, FALSE);
  205.             break;
  206.  
  207.          case SIZEVERIFY:
  208.             dont_draw = 1;
  209.             break;
  210.          }
  211.          ReplyMsg(msg);
  212.       } /* while */
  213.       if (GetMsg(timerport)) {
  214.          redraw(w, FALSE);
  215.          starttimer();
  216.       }
  217.    } /* for */
  218. }
  219.  
  220. #define TOP w->BorderTop
  221. #define BOTTOM w->Height - w->BorderBottom
  222. #define LEFT w->BorderLeft
  223. #define RIGHT w->Width - w->BorderRight
  224. #define GUTTER 3        /* pixels of veritical spacing between bars */
  225.  
  226. /*
  227.  *  Redraw all of the stuff in the window.
  228.  */
  229. redraw(w, refresh)
  230.    struct Window *w;
  231.    int refresh;
  232. {
  233.    register struct RastPort *rp = w->RPort;
  234.    register short x_min, y_min, x_max, y_max;
  235.    static short AvailWidth, AvailHeight, HorizSpace, Thickness, Scale;
  236.  
  237.    if (dont_draw)
  238.       return 0;
  239.    getsizes();
  240.    if (refresh) {
  241.       SetAPen(rp, 2);
  242.       SetBPen(rp, 2);
  243.       SetOPen(rp, 2);
  244.       RectFill(rp, LEFT, TOP, RIGHT, BOTTOM);
  245.       /*  recalculate the spacing paramters for this sized window */
  246.       AvailWidth = w->Width - w->BorderRight - w->BorderLeft;
  247.       AvailHeight = w->Height - w->BorderTop - w->BorderBottom;
  248.       HorizSpace = AvailWidth/20; /* use 5% of available space as margin */
  249.       AvailWidth -= HorizSpace * 2;
  250.       Thickness = (AvailHeight - GUTTER*3) / 2;
  251.       if (ChipMax > FastMax)
  252.          Scale = ChipMax/AvailWidth;
  253.       else
  254.          Scale = FastMax/AvailWidth;
  255.    }
  256.    SetAPen(rp, 3);
  257.    SetOPen(rp, 1);
  258.    SetBPen(rp, 2);
  259.    x_min = HorizSpace;
  260.    y_min = TOP + GUTTER;
  261.    x_max = x_min + (ChipMax - ChipFree)/Scale;
  262.    y_max = y_min + Thickness;
  263.    RectFill(rp, x_min, y_min, x_max, y_max);
  264.    x_min = x_max;
  265.    x_max = x_min + ChipFree/Scale;
  266.    SetAPen(rp, 0);
  267.    RectFill(rp, x_min, y_min, x_max, y_max);
  268.    x_min = HorizSpace;
  269.    x_max = x_min + (FastMax - FastFree)/Scale;
  270.    y_min = y_max + GUTTER;
  271.    y_max = y_min + Thickness;
  272.    SetAPen(rp, 3);
  273.    RectFill(rp, x_min, y_min, x_max, y_max);
  274.    x_min = x_max;
  275.    x_max = x_min + FastFree/Scale;
  276.    SetAPen(rp, 0);
  277.    RectFill(rp, x_min, y_min, x_max, y_max);
  278. }
  279.